from copy import deepcopy
from datetime import timedelta, datetime, timezone
from typing import Any

from fastapi import HTTPException, status
from jose import jwt, JWTError

SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE = timedelta(weeks=1)


def create_jwt_token(data: dict[str, Any], expires_delta: timedelta = ACCESS_TOKEN_EXPIRE) -> str:
    """
    创建jwt令牌
    :param data: 需要加密的数据
    :param expires_delta: 过期的时间
    :return:
    """
    # 深拷贝
    copy_data = deepcopy(data)
    # 判断过期时间是否存在
    if expires_delta:
        # 过期时间 = 当前utc时间 + 传入的增量
        expire = datetime.now(timezone.utc) + expires_delta
    else:
        # 过期时间 = 当前utc时间 + 增量
        expire = datetime.now(timezone.utc) + ACCESS_TOKEN_EXPIRE
    # 将过期时间添加进数据
    copy_data.update({"exp": expire})
    # 加密成jwt令牌
    return jwt.encode(copy_data, SECRET_KEY, algorithm=ALGORITHM)


def parse_jwt_token(token: str) -> dict[str, Any]:
    """
    解析jwt令牌
    :param token: jwt令牌
    :return:
    """
    # 自定义异常
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        # 解析jwt token
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        # 拿到过期时间
        expire = payload.get("exp")
        # 如果过期时间不存在
        if expire is None:
            # 触发报错
            raise credentials_exception
        # 如果时间过期
        if datetime.now().timestamp() >= expire:
            # 触发报错
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    return payload
